package userDao

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/garyburd/redigo/redis"
	commonmodel "helloword01/31chatroom/common/model"
)

// MyUserDao 我们在服务器启动后，就初始化一个userDao实例，
// 把它做成全局的变量，在需要和redis操作时，就直接使用即可
// 拉取包：go get github.com/garyburd/redigo/redis
// 拉取包：go get github.com/go-redis/redis/v8

var MyUserDao *UserDao

// UserDao
// @Description:
type UserDao struct {
	pool *redis.Pool
}

// InitUserDao
//
//	@Description:
//	@param pool
//	@return userDao
func InitUserDao(pool *redis.Pool) (userDao *UserDao) {
	MyUserDao = &UserDao{
		pool: pool,
	}
	MyUserDao.initUsers()
	return MyUserDao
}

// getUserById 通过id获取用户信息
//
//	@Description:
//	@receiver this
//	@param conn
//	@param id
//	@return u
//	@return err
func (this *UserDao) getUserById(conn redis.Conn, id int) (u *commonmodel.User, err error) {
	res, err := redis.String(conn.Do("HGet", "users", id))
	if err != nil {
		if errors.Is(err, redis.ErrNil) { //表示在 users 哈希中，没有找到对应id
			err = commonmodel.ErrorUserNotExists
		}
		return
	}
	u = &commonmodel.User{}
	err = json.Unmarshal([]byte(res), u)
	if err != nil {
		fmt.Println("json.Unmarshal err=", err)
		return
	}
	return
}

// Login 执行登录
//
//	@Description:
//	@receiver this
//	@param userId
//	@param userPwd
//	@return user
//	@return err
func (this *UserDao) Login(userId int, userPwd string) (user *commonmodel.User, err error) {
	conn := this.pool.Get()
	defer CloseConn(conn)
	user, err = this.getUserById(conn, userId)
	if err != nil {
		return
	}
	if user.UserPwd != userPwd {
		err = commonmodel.ErrorUserPwd
		return
	}
	return
}

// Register 注册用户
//
//	@Description:
//	@receiver this
//	@param user
//	@return err
func (this *UserDao) Register(user *commonmodel.User) (err error) {
	conn := this.pool.Get()
	defer CloseConn(conn)
	_, err = this.getUserById(conn, user.UserId)
	if err == nil {
		err = commonmodel.ErrorUserExists
		return
	}
	//这时，说明id在redis还没有，则可以完成注册
	data, err := json.Marshal(user) //序列化
	if err != nil {
		return
	}
	//入库
	_, err = conn.Do("HSet", "users", user.UserId, string(data))
	if err != nil {
		fmt.Println("保存注册用户错误 err=", err)
		return
	}
	return
}

// initUsers 初始化一些用户
//
//	@Description:
//	@receiver this
func (this *UserDao) initUsers() {
	conn := this.pool.Get()
	defer CloseConn(conn)
	for i := 1; i <= 10; i++ {
		u := commonmodel.User{
			UserId:   i,
			UserName: "user" + fmt.Sprintf("%d", i),
			UserPwd:  "123456",
		}
		data1, err := json.Marshal(&u)
		if err == nil {
			_, err = conn.Do("HSet", "users", u.UserId, string(data1))
			if err != nil {
				fmt.Println(err)
			}
		}
	}
}

func CloseConn(conn redis.Conn) {
	if conn != nil {
		err := conn.Close()
		if err != nil {
			fmt.Println("conn close err=", err)
		}
	}
}
